package com.gopay.common.log.aop;

import com.gopay.common.log.annotation.LogX;
import com.gopay.common.log.collect.LogBag;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.UUID;

/**
 * 日志注解AOP
 * 
 * @LogAop.java
 * @author dak.wang
 * @2016年4月6日 下午6:24:01 www.gopay.com.cn Inc.All rights reserved.
 */
@Aspect
@Component
public class LogAop {

	@Autowired
	private LogAopAdviceComponent logAopAdviceComponent;

	private static Logger errorlogger = Logger.getLogger(LogAop.class);

    @Pointcut("@annotation(com.gopay.common.log.annotation.LogX)")
    private void aspectjMethod() {
    };

    @Around("aspectjMethod()")
    public Object aroundMethod(ProceedingJoinPoint pjd) throws Throwable {
    	LogBag logBag = new LogBag();
    	String bagId = "";
    	try{
	
	        bagId = UUID.randomUUID().toString();
	        logBag.setId(bagId);
	
	        // MethodInvocationProceedingJoinPoint
	        // mjp=(MethodInvocationProceedingJoinPoint)pjd;
	
	        String methodName = pjd.getSignature().getName();
	
	        Method method = null;
	        Method[] marr = pjd.getTarget().getClass().getDeclaredMethods();
	        for (int i = 0; i < marr.length; i++) {
	            if (marr[i].getName().equals(methodName)) {
	                method = marr[i];
	                break;
	            }
	        }
	
	        logBag.setHasTransactionalAnno(
	                method.getAnnotation(org.springframework.transaction.annotation.Transactional.class) != null);
	
	        Annotation ann = method.getAnnotation(com.gopay.common.log.annotation.LogX.class);
	        if (ann != null) {
	            LogX logx = (LogX) ann;
				/**** modify by sh.jiao 20170524 修改logX注解 start****/
	            /*logBag.setPlatform(logx.platform().value);
	            logBag.setCategory(logx.category().value);*/
	            String operTypeCd = logx.operTypeCd();
	            logBag.setPlatform(operTypeCd.substring(0,2));
	            logBag.setCategory(operTypeCd.substring(2,4));
	            logBag.setModules(operTypeCd.substring(4,6));
	            logBag.setOperTypeCd(logx.operTypeCd());
				/**** modify by sh.jiao 20170524 修改logX注解 end****/
	        }
    	}catch(Exception e){
    		errorlogger.error("aroundMethod方法抛出异常",e);
    	}

        try {
			logAopAdviceComponent.beforeAdvice(logBag);
            //LogAopAdviceUtil.beforeAdvice(logBag);

            Object result = pjd.proceed();
			logAopAdviceComponent.afterReturningAdvice(bagId);
            //LogAopAdviceUtil.afterReturningAdvice(bagId);

            return result;
        } catch (Exception e) {
			logAopAdviceComponent.afterThrowingAdvice(bagId, e);
            //LogAopAdviceUtil.afterThrowingAdvice(bagId, e);
            throw e;
        }

    }

}
